// 📦 引入工具库
const _ = require("lodash");
const path = require("path");
const fs = require("fs");

// 📦 ESM 支持模块加载
const esm = require("esm");
const requireModule = esm(module);

// 📦 项目依赖模块
const { readAllValues } = requireModule(
  "../../../awakened-potential/helpers/readAllValues.js"
);
const checkAccuracy = requireModule("../../utils/checkAccuracy.js");

// ✅ 读取历史开奖数据（模拟全部）
const allValues = readAllValues("m");

console.log(allValues.length);

// ✅ 号码池（01 ~ 49）
const allNumbers = Array.from({ length: 49 }, (_, i) =>
  (i + 1).toString().padStart(2, "0")
);

// ✅ 是否使用窗口
const useWindow = true;

// 预测结果统计变量
let predictResults = [];
let correct = 0;
let maxWrongStreak = 0;
let currentWrongStreak = 0;

// 记录历史号码的预测准确率
const predictionHistory = [];

// ✅ 计算连续错误数
function calculateConsecutiveWrongCount() {
  let consecutiveCount = 0;
  for (let i = predictionHistory.length - 1; i >= 0; i--) {
    if (!predictionHistory[i].isCorrect) {
      consecutiveCount++;
    } else {
      break;
    }
  }
  return consecutiveCount;
}

// ✅ 策略函数：减少连续错误次数
function select32NumbersWithMinError(temp, windowSize) {
  // 获取过去 `windowSize` 期的预测号码历史
  const selectedNumbers = [];
  const uniqueNumbers = new Set();

  // 获取一个周期性的预测结果
  allNumbers.forEach((num) => {
    if (uniqueNumbers.size >= 32) return; // 已经选择了32个号码

    if (temp.some((item) => item.number === num)) {
      uniqueNumbers.add(num);
    }
  });

  // 如果不足32个，补充其他频繁出现的号码
  if (uniqueNumbers.size < 32) {
    const missingNumbers = allNumbers.filter((num) => !uniqueNumbers.has(num));
    missingNumbers.slice(0, 32 - uniqueNumbers.size).forEach((num) => uniqueNumbers.add(num));
  }

  return Array.from(uniqueNumbers);
}

// ✅ 外部循环：遍历不同的窗口大小
const testResults = [];

// ✅ 循环windowSize从2到200进行测试
for (let windowSize = 2; windowSize <= 200; windowSize++) {
  let correctCount = 0;
  let wrongStreak = 0;
  let maxWrongStreakLocal = 0;
  let localPredictionResults = [];

  // 重置历史预测记录
  predictionHistory.length = 0;

  // ✅ 主循环：遍历每一期数据
  allValues.forEach((item, index) => {
    const temp = useWindow
      ? allValues.slice(index - windowSize, index)
      : allValues.slice(0, index);

    if (temp.length === 0) return;

    // 选择32个号码，减少连续错误
    const selectedNumbers = select32NumbersWithMinError(temp, windowSize);

    // 校验是否选出32个不重复号码
    if (selectedNumbers.length !== 32) {
      throw new Error("选出的32个号码数量不正确");
    }

    try {
      // 判断预测的准确性
      const isPredictionCorrect = checkAccuracy(selectedNumbers, item.number);

      // 更新历史预测结果
      predictionHistory.push({
        numbers: selectedNumbers,
        isCorrect: isPredictionCorrect
      });

      // 如果预测正确，重置连续错误数
      if (isPredictionCorrect) {
        correctCount += 1;
        wrongStreak = 0;
      } else {
        wrongStreak += 1;
        maxWrongStreakLocal = Math.max(maxWrongStreakLocal, wrongStreak);
      }

      localPredictionResults.push(selectedNumbers);
    } catch (error) {
      console.error(`Error in checkAccuracy at index ${index}: ${error.message}`);
    }
  });

  // 计算准确率
  const totalPredictions = localPredictionResults.length;
  const accuracy = totalPredictions > 0 ? ((correctCount / totalPredictions) * 100).toFixed(2) : 0;

  // 输出当前窗口大小的统计数据
  console.log(`Window Size: ${windowSize}`);
  console.log(`命中次数: ${correctCount}`);
  console.log(`准确率: ${accuracy}%`);
  console.log(`最大连续错误次数: ${maxWrongStreakLocal}`);

  // 统计所有窗口大小的结果
  testResults.push({
    windowSize,
    accuracy: parseFloat(accuracy),
    maxWrongStreak: maxWrongStreakLocal,
  });
}

// ✅ 输出所有结果
console.log("📊 所有 windowSize 结果:");
console.table(testResults);

// ✅ 输出最小连续错误的结果
const minWrong = _.minBy(testResults, "maxWrongStreak");
console.log("\n🧱 最小连续错误窗口:");
console.log(minWrong);

// ✅ 输出最大准确率的结果
const maxAcc = _.maxBy(testResults, "accuracy");
console.log("\n🎯 最大准确率窗口:");
console.log(maxAcc);
